package cn.qfys521.mc_websocket.client.models

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

/**
 * 玩家基础结构（PlayerDto）。
 * @property name 玩家名称（可选）。
 * @property id 玩家 UUID，带连字符（可选；请求解析时优先于名称）。
 */
@Serializable
data class Player(
    val name: String? = null,
    val id: String? = null,
)

/**
 * 管理员基础结构（OperatorDto）。
 * @property permissionLevel 权限等级（0..4，可选）。
 * @property bypassesPlayerLimit 是否可绕过最大玩家数限制（可选）。
 * @property player 对应玩家（可选）。
 */
@Serializable
data class Operator(
    val permissionLevel: Int? = null,
    val bypassesPlayerLimit: Boolean? = null,
    val player: Player? = null,
)

/**
 * 版本信息结构。
 * @property protocol 协议版本号。
 * @property name 版本名称。
 */
@Serializable
data class Version(
    val protocol: Int,
    val name: String,
)

/**
 * 服务端状态（ServerState）。
 * @property players 在线玩家列表（可能为空）。
 * @property started 服务端是否已启动。
 * @property version 服务端版本信息。
 */
@Serializable
data class ServerState(
    val players: List<Player> = emptyList(),
    val started: Boolean,
    val version: Version,
)

/**
 * 文本消息组件（用于系统消息或踢出提示）。
 * 三者互斥优先：translatable(+params) > literal。
 * @property translatable 本地化键名（可选）。
 * @property translatableParams 本地化参数（可选）。
 * @property literal 直接文本（可选）。
 */
@Serializable
data class Message(
    val translatable: String? = null,
    val translatableParams: List<String>? = null,
    val literal: String? = null,
)

/**
 * 系统消息负载（server/system_message）。
 * @property receivingPlayers 指定接收玩家（不指定则广播）。
 * @property overlay 是否覆盖显示（忽略聊天可见性）。
 * @property message 文本消息内容。
 */
@Serializable
data class SystemMessage(
    val receivingPlayers: List<Player>? = null,
    val overlay: Boolean,
    val message: Message,
)

/**
 * 踢出玩家请求负载（players/kick）。
 * @property players 要踢出的玩家列表。
 * @property message 可选提示消息。
 */
@Serializable
data class KickPlayer(
    val players: List<Player>,
    val message: Message? = null,
)

/**
 * 封禁玩家条目（UserBanDto）。
 * @property reason 原因（可选）。
 * @property expires 过期时间（可选，字符串）。
 * @property source 操作者（可选）。
 * @property player 目标玩家（必选）。
 */
@Serializable
data class UserBan(
    val reason: String? = null,
    val expires: String? = null,
    val source: String? = null,
    val player: Player,
)

/**
 * 封禁 IP 条目（IpBanDto）。
 * @property reason 原因（可选）。
 * @property expires 过期时间（可选，字符串）。
 * @property ip IP 地址（必选）。
 * @property source 操作者（可选）。
 */
@Serializable
data class IpBan(
    val reason: String? = null,
    val expires: String? = null,
    val ip: String,
    val source: String? = null,
)

/**
 * 添加封禁 IP 的请求条目（ip_bans/add）。
 * 可通过 ip 或 player 指定来源，服务端会解析玩家当前 IP。
 * @property reason 原因（可选）。
 * @property expires 过期时间（可选，字符串）。
 * @property ip 直接指定的 IP（可选）。
 * @property source 操作者（可选）。
 * @property player 目标玩家（可选）。
 */
@Serializable
data class IncomingIpBan(
    val reason: String? = null,
    val expires: String? = null,
    val ip: String? = null,
    val source: String? = null,
    val player: Player? = null,
)

/**
 * 已类型化的游戏规则条目。
 * @property type 规则类型（boolean 或 integer）。
 * @property value 当前值（字符串表示）。
 * @property key 规则键名。
 */
@Serializable
data class TypedGameRule(
    val type: RuleType,
    val value: String,
    val key: String,
) {
    /** 规则类型枚举。 */
    @Serializable
    enum class RuleType {
        @SerialName("integer") INTEGER,
        @SerialName("boolean") BOOLEAN,
    }
}

/**
 * 待更新的游戏规则条目（无显式类型，服务端按规则定义解析）。
 * @property value 设置的值（字符串）。
 * @property key 规则键名。
 */
@Serializable
data class UntypedGameRule(
    val value: String,
    val key: String,
)
